<?php
declare (strict_types = 1);

namespace app\command;

use app\api\model\BaseConfig as BaseConfigModel;
use app\api\model\MemberTransaction as MemberTransactionModel;
use app\common\model\UserMoneyLog as UserMoneyLogModel;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use think\facade\Db;
use Workerman\Worker;
use Workerman\Lib\Timer;
use think\facade\Queue;

class Entrust extends Command
{
    protected $timer_id;

    protected function configure()
    {
        // 指令配置
        $this->setName('entrust')
            ->addArgument('action', Argument::OPTIONAL, "start|stop|restart|reload|status|connections", 'start')
            ->addOption('mode', 'm', Option::VALUE_OPTIONAL, 'Run the workerman server in daemon mode.')
            ->setDescription('entrust');
    }

    protected function execute(Input $input, Output $output)
    {
        $action = $input->getArgument('action');

        $mode = $input->getOption('mode');

        global $argv;

        $argv = [];

        array_unshift($argv, 'think', $action);
        if ($mode == 'd') {
            $argv[] = '-d';
        } else if ($mode == 'g') {
            $argv[] = '-g';
        }

        $task = new Worker();

        $task->onWorkerStart = function()
        {
            $this->timer_id = Timer::add(1, function()
            {
                $begin_time =time();

                $buy_data = Db::name('member_entrust')->where([['entrust_state','=',1],['transaction_state','=',1]])->order('money desc create_time asc')->limit(20)->select()->toArray();

                foreach ($buy_data as $k=>$v)
                {
                    $sell_data = Db::name('member_entrust')->lock(true)->where([['entrust_state','=',1],['transaction_state','=',2],['money','<=',$v['money']]])->limit(20)->order('money asc')->select()->toArray();

                    foreach ($sell_data as $key=>$val)
                    {

                        $buy_data1 = Db::name('member_entrust')->lock(true)->where('id',$v['id'])->find();

                        //获取买方剩余数量
                        $buy_num =  bcsub($buy_data1['num'],$buy_data1['already_num'],2);

                        //获取卖方剩余数量
                        $sell_num = bcsub($val['num'],$val['already_num'],2);

                        if($buy_num > $sell_num)
                        {
                            if($sell_num > 0 && $buy_num > 0)
                            {
                                Db::startTrans();
                                try {

                                    $deal_price = ($v['money'] > $v['price_hook']) ? $val['money'] : $v['money'];

                                    Db::name('member_entrust')->where('id', $v['id'])->inc('already_num', (float)$sell_num)->update(['deal_price'=>$deal_price]);

                                    Db::name('member_entrust')->where('id', $val['id'])->inc('already_num', (float)$sell_num)->update(['entrust_state' => 2,'deal_price'=>$deal_price]);

                                    /*$data['buy_data'] = $v;

                                    $data['sell_data'] = $val;

                                    $data['price'] = $sell_num;

                                    $jobHandlerClassName = 'app\job\Task@fire';

                                    $jobQueueName = 'entrust';

                                    Queue::push($jobHandlerClassName, $data, $jobQueueName);*/

                                    //计算返还U的数量
                                    $return = bcmul($deal_price,$v['num'],4);

                                    if($v['u_buy_price'] > $return)UserMoneyLogModel::change($v['mid'],'usdt',bcsub($v['u_buy_price'],$return,2),'Transaction return','','交易委托增加'.bcsub($v['u_buy_price'],$return,2).'usdt');

                                    MemberTransactionModel::add_transaction($v['mid'],1,$deal_price,$sell_num,1,0,2,$v['id'],$val['mid']);

                                    MemberTransactionModel::add_transaction($val['mid'],2,$deal_price,$sell_num,2,transaction_commission($sell_num,$deal_price),2,$val['id'],$v['mid']);

                                    UserMoneyLogModel::change($v['mid'],'adc',bcmul($deal_price,$sell_num,4),'Transaction buy','','交易增加'.bcmul($deal_price,$sell_num,4).'adc');

                                    $usdt_obtain = commission("$sell_num",$deal_price);

                                    UserMoneyLogModel::change($val['mid'],'usdt',$usdt_obtain,'Transaction sell','','交易增加'.$usdt_obtain.'usdt');

                                    Db::commit();
                                } catch (\Exception $e) {
                                    // 回滚事务
                                    Db::rollback();
                                }
                            }

                        }else if($buy_num == $sell_num)
                        {
                            if($sell_num > 0 && $buy_num > 0)
                            {
                                Db::startTrans();
                                try {

                                    $deal_price = ($v['money'] > $v['price_hook']) ? $val['money'] : $v['money'];

                                    Db::name('member_entrust')->where('id',$v['id'])->inc('already_num',(float)$buy_num)->update(['entrust_state' => 2,'deal_price'=>$deal_price]);

                                    Db::name('member_entrust')->where('id',$val['id'])->inc('already_num',(float)$buy_num)->update(['entrust_state' => 2,'deal_price'=>$deal_price]);

                                    /*$data['buy_data'] = $v;

                                    $data['sell_data'] = $val;

                                    $data['price'] = $buy_num;

                                    $jobHandlerClassName = 'app\job\Task@fire';

                                    $jobQueueName = 'entrust';

                                    Queue::push($jobHandlerClassName, $data, $jobQueueName);*/

                                    //计算返还U的数量
                                    $return = bcmul($deal_price,$v['num'],4);

                                    if($v['u_buy_price'] > $return)UserMoneyLogModel::change($v['mid'],'usdt',bcsub($v['u_buy_price'],$return,2),'Transaction return','','交易委托增加'.bcsub($v['u_buy_price'],$return,2).'usdt');

                                    MemberTransactionModel::add_transaction($v['mid'],1,$deal_price,$buy_num,1,0,2,$v['id'],$val['mid']);

                                    MemberTransactionModel::add_transaction($val['mid'],2,$deal_price,$buy_num,2,transaction_commission($buy_num,$deal_price),2,$val['id'],$v['mid']);

                                    UserMoneyLogModel::change($v['mid'],'adc',bcmul($deal_price,$buy_num,4),'Transaction buy','','交易增加'.bcmul($deal_price,$buy_num,4).'adc');

                                    $usdt_obtain = commission("$buy_num",$deal_price);

                                    UserMoneyLogModel::change($val['mid'],'usdt',$usdt_obtain,'Transaction sell','','交易增加'.$usdt_obtain.'usdt');

                                    Db::commit();
                                } catch (\Exception $e) {
                                    // 回滚事务
                                    Db::rollback();
                                }
                            }
                        }else
                        {
                            if($sell_num > 0 && $buy_num > 0)
                            {
                                Db::startTrans();
                                try {

                                    $deal_price = ($v['money'] > $v['price_hook']) ? $val['money'] : $v['money'];

                                    Db::name('member_entrust')->where('id',$v['id'])->inc('already_num',(float)$buy_num)->update(['entrust_state' => 2,'deal_price'=>$deal_price]);

                                    Db::name('member_entrust')->where('id',$val['id'])->inc('already_num',(float)$buy_num)->update(['deal_price'=>$deal_price]);

                                    /* $data['buy_data'] = $v;

                                     $data['sell_data'] = $val;

                                     $data['price'] = $buy_num;

                                     $jobHandlerClassName = 'app\job\Task@fire';

                                     $jobQueueName = 'entrust';

                                     Queue::push($jobHandlerClassName, $data, $jobQueueName);*/

                                    //计算返还U的数量
                                    $return = bcmul($deal_price,$v['num'],4);

                                    if($v['u_buy_price'] > $return)UserMoneyLogModel::change($v['mid'],'usdt',bcsub($v['u_buy_price'],$return,2),'Transaction return','','交易委托增加'.bcsub($v['u_buy_price'],$return,2).'usdt');

                                    MemberTransactionModel::add_transaction($v['mid'],1,$deal_price,$buy_num,1,0,2,$v['id'],$val['mid']);

                                    MemberTransactionModel::add_transaction($val['mid'],2,$deal_price,$buy_num,2,transaction_commission($buy_num,$deal_price),2,$val['id'],$v['mid']);

                                    UserMoneyLogModel::change($v['mid'],'adc',bcmul($deal_price,$buy_num,4),'Transaction buy','','交易增加'.bcmul($deal_price,$buy_num,4).'adc');

                                    $usdt_obtain = commission("$buy_num",$deal_price);

                                    UserMoneyLogModel::change($val['mid'],'usdt',$usdt_obtain,'Transaction sell','','交易增加'.$usdt_obtain.'usdt');

                                    Db::commit();
                                } catch (\Exception $e) {
                                    // 回滚事务
                                    Db::rollback();
                                }
                            }
                        }
                    }

                }


                $end_time =time();

                $this->output->writeln('时间：'.date('H:i:s',time()));

                $this->output->writeln('修改买数据：'.count($buy_data));

                $this->output->writeln('修改卖数据：'.count($sell_data));

                $this->output->writeln('用时：'.$this->get_timediff($begin_time,$end_time));

                $this->output->writeln('结束');
            });
        };
        $task->onClose = function()
        {
            Timer::del($this->timer_id);
        };
        // 运行worker
        Worker::runAll();
    }


    function get_timediff($begin_time,$end_time)
    {
        if($begin_time < $end_time){
            $starttime = $begin_time;
            $endtime = $end_time;
        }else{
            $starttime = $end_time;
            $endtime = $begin_time;
        }
        //计算天数
        $timediff = $endtime-$starttime;
        $days = intval($timediff/86400);
        //计算小时数
        $remain = $timediff%86400;
        $hours = intval($remain/3600);
        //计算分钟数
        $remain = $remain%3600;
        $mins = intval($remain/60);
        //计算秒数
        $secs = $remain%60;

        return "{$mins}分{$secs}秒";
    }
}
